package com.billionsfinance.hessian.core;

import com.billionsfinance.hessian.annotation.HessianService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.remoting.caucho.HessianServiceExporter;

import java.util.Map;
import java.util.Set;

/**
 * @ ClassName: HessianServerBeanFactory.java
 * @ Author: WeiHui-Z
 * @ Date: 2017/1/3 13:06
 * @ Version: v1.0.0
 */
public class HessianServerBeanFactory implements ApplicationContextAware {

    private static final Logger LOGGER = LoggerFactory.getLogger(HessianServerBeanFactory.class);

    /**
     * 访问后缀
     */
    private String suffix = "";

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        ConfigurableApplicationContext context = (ConfigurableApplicationContext) applicationContext;
        Map<String, Object> beans = context.getBeanFactory().getBeansWithAnnotation(HessianService.class);
        Set<Map.Entry<String, Object>> entries = beans.entrySet();
        for (Map.Entry<String, Object> entry : entries) {
            String refBean = entry.getKey();
            Object value = entry.getValue();
            Class<?> clazz = value.getClass();
            Class<?> interfaces = clazz.getInterfaces()[0];

            LOGGER.info("Register hessian server bean: {}", clazz);
            registerBeanDefinition(context, refBean, interfaces);
        }
    }

    /**
     * 创建bean并且放入springBean工厂，取代xml的繁琐配置
     *
     * @param context                   bean上下文
     * @param hessianServiceImplRefBean serviceImpl--bean 的名称
     * @param hessianServiceInterface   service的全类名
     */
    private void registerBeanDefinition(ConfigurableApplicationContext context, String hessianServiceImplRefBean, Class<?> hessianServiceInterface) {
        // 通过BeanDefinitionBuilder创建bean定义
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(HessianServiceExporter.class);
        // 设置属性userAcctDAO,此属性引用已经定义的bean:userAcctDAO
        beanDefinitionBuilder.addPropertyReference("service", hessianServiceImplRefBean);
        beanDefinitionBuilder.addPropertyValue("serviceInterface", hessianServiceInterface.getName());
        // 获取bean工厂并转换为DefaultListableBeanFactory
        DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) context.getBeanFactory();
        // 注册bean
        String hessianServerUrl = "/" + hessianServiceInterface.getSimpleName() + suffix;
        LOGGER.info("Register hessian server url: {}", hessianServerUrl);
        beanFactory.registerBeanDefinition(hessianServerUrl, beanDefinitionBuilder.getRawBeanDefinition());
    }

    public void setSuffix(String suffix) {
        this.suffix = suffix;
    }
}